/*
 *  Copyright (c) 2018, Infineon Technologies AG
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification,are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 *  - Neither the name of the copyright holders nor the names of its contributors
 *  may be used to endorse or promote products derived from this software without
 *  specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  To improve the quality of the software, users are encouraged to share
 *  modifications, enhancements or bug fixes with Infineon Technologies AG
 *  dave@infineon.com).
 */
/**
 * \defgroup communication Communication
 * @{
 */
/**
 * \file	communication.c
 * \author 	Manuel Escudero Rodriguez
 * \date	08.05.2018
 * \brief   Communication functions
 */
#include <DAVE.h>
#include "communication.h"
#include "config_adc.h"
#include "controller_boost.h"
#include "controller_buck.h"

/** \todo Reserve memory space in the linker file for this area. */
/** Address of the configurable parameters. To be used during Flash access. Note: 256 bytes per page. */
const params_t *parameters_ROM = (params_t *)XMC_FLASH_SECTOR_8;
/** Copy of the configurable parameters. To store modified parameters this intermediate storage is required (due to the behavior of FLASH memory during erase, copy procedures). */
params_t parameters_RAM;
/** Copy of the configurable parameters. To store modified parameters this intermediate storage is required (due to the behavior of FLASH memory during erase, copy procedures). */
params_t parameters_MIN_RAM;
/** Copy of the configurable parameters. To store modified parameters this intermediate storage is required (due to the behavior of FLASH memory during erase, copy procedures). */
params_t parameters_MAX_RAM;
/** Default parameters used until first storage by the user through the GUI. */
params_t parameters_DFLT =
{
	.voltage_reference = 14250,//13500,//14331,//12950,//12920,//12930,//49.1V//14331,-->54V
	.dead_time_A_B = 20,
	.dead_time_C_D = 28,
	.boost_dead_time_A_B = 20,
	.boost_dead_time_C_D = 28,
	.synch_OFF_dly = 15,
	.synch_OFF_il_ratio = 10,
	.synch_OFF_il_factor = 10,
	.synch_ON_dly = 8,
	.synch_ON_DCM_dly = 6,
	.synch_ON_il_ratio = 10,
	.synch_ON_il_factor = 2,
	.synch_DCM = 465,
	.synch_ICP = 120,
	.bridge_A_B_il_factor = 0,
	.bridge_C_D_il_factor = 2,
	.bridge_il_ratio = 10,
	.min_phase = 260,
	.burst_stop_limit = 300,
	.burst_low_limit = 350,
	.burst_high_limit = 390,
	.burst_phase = 300,
	.burst_trap_cyc = 50,
	.burst_lenght = 50,
	.vin_min_high = 9764,
	.debug_vin = 0,
	.debug_soft = 0,
	.debug_fan = 0
};
/** Default minimum values for the stored parameters. */
params_t parameters_MIN =
{
    .voltage_reference = 1000, // Arbitrary chosen
    .dead_time_A_B = 5, // No limitation from the uc. point of view, but would not be safe for the converter less than this.
    .dead_time_C_D = 5, // It is not possible to achieve less than this due to the chaining of C and D.
    .boost_dead_time_A_B = 5, // No limitation from the uc. point of view, but would not be safe for the converter less than this.
    .boost_dead_time_C_D = 5, // It is not possible to achieve less than this due to the chaining of C and D.
	.synch_OFF_dly = 0,
	.synch_OFF_il_ratio = 0,
	.synch_OFF_il_factor = 0,
	.synch_ON_dly = 0,
	.synch_ON_DCM_dly = 0,
	.synch_ON_il_ratio = 0,
	.synch_ON_il_factor = 0,
	.synch_DCM = 0,
	.synch_ICP = 0,
	.bridge_A_B_il_factor = 0,
	.bridge_C_D_il_factor = 0,
	.bridge_il_ratio = 0,
	.min_phase = 0,
	.burst_stop_limit = 0,
	.burst_low_limit = 0,
	.burst_high_limit = 0,
	.burst_phase = 0,
	.burst_trap_cyc = 0,
	.burst_lenght = 2,
	.vin_min_high = 100
};
/** Default maximum values for the stored parameters. */
params_t parameters_MAX =
{
    .voltage_reference = 16383, // Arbitrary chosen as the maximum ADC output
    .dead_time_A_B = 200, // Arbitrary chosen, maximum would be 255
    .dead_time_C_D = 200, // Arbitrary chosen, maximum would be 255
    .boost_dead_time_A_B = 200, // Arbitrary chosen, maximum would be 255
    .boost_dead_time_C_D = 200, // Arbitrary chosen, maximum would be 255
	.synch_OFF_dly = 200, // Arbitrary chosen
	.synch_OFF_il_ratio = 16, // The measurement is 14 bits wide
	.synch_OFF_il_factor = 50, // Arbitrary chosen
	.synch_ON_dly = 200, // Arbitrary chosen
	.synch_ON_DCM_dly = 200, // Arbitrary chosen
	.synch_ON_il_ratio = 16, // The measurement is 14 bits wide
	.synch_ON_il_factor = 50, // Arbitrary chosen
	.synch_DCM = 16383, // Arbitrary chosen
	.synch_ICP = 16383, // Arbitraty chosen
	.bridge_il_ratio = 16,
	.bridge_A_B_il_factor = 50,
	.bridge_C_D_il_factor = 50,
	.min_phase = PWM_PEAK_REF_MAX,
	.burst_stop_limit = PWM_PEAK_REF_MAX,
	.burst_low_limit = PWM_PEAK_REF_MAX,
	.burst_high_limit = PWM_PEAK_REF_MAX,
	.burst_phase = PWM_PEAK_REF_MAX,
	.burst_trap_cyc = PWM_PEAK_REF_MAX,
	.burst_lenght = 200, // Arbitrary
	.vin_min_high = 16383
};
/** Selection of transmission data block. See uart_transmit function. */
static uint32_t msg_cnt = 100;
/** UART reception buffer */
static msg_t UART_rx_buffer;
/*---------------------------------------------------------------------------*/
/**
 * \brief   Limit the value insight of the range between min and max.
 * \return  Limited value.
 * \param	value	Value to be limited.
 * \param	min		Minimum possible value.
 * \param	max		Maximum possible value.
 *
 * Mostly useful after first run of the software, when all the parameters might
 * be 0 after uploading the firmware, what could be dangerous situation.
 */
static inline uint16_t limit_range(uint16_t value, uint16_t min, uint16_t max)
{
	uint16_t limited_value;
    if(value < min)
    {
        limited_value = min;
    }
    else if(value > max)
    {
        limited_value = max;
    }
    else
    {
    	limited_value = value;
    }
    return limited_value;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief   UART execute received command and data.
 * \return  None
 *
 * Non blocking function. No interrupts involved.
 * The command and the data are stored in a static buffer. The reception functions
 * may have filled those buffers before calling this function.
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void uart_execute_cmd()
{
    /* The command is stored in the first byte of a message. */
    switch(UART_rx_buffer.msg.command)
    {
        case UART_OUT_V:
            /* Store output voltage setting and checks range of the value */
        	parameters_RAM.voltage_reference = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.voltage_reference, parameters_MAX_RAM.voltage_reference);
            break;
        case UART_VIN_MIN_HIGH:
			/* Store output voltage setting and checks range of the value */
			parameters_RAM.vin_min_high = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.vin_min_high, parameters_MAX_RAM.vin_min_high);
			break;
        case UART_READ:
            /* Read out all parameters. See uart_transmit function. */
            msg_cnt = 0;
            break;
        case UART_DT_A_B:
            /* Store dead time A B settings and checks range of the value */
        	parameters_RAM.dead_time_A_B = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.dead_time_A_B, parameters_MAX_RAM.dead_time_A_B);
            break;
        case UART_DT_C_D:
            /* Store dead time C D settings and checks range of the value */
        	parameters_RAM.dead_time_C_D = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.dead_time_C_D, parameters_MAX_RAM.dead_time_C_D);
            break;
        case BOOST_UART_DT_A_B:
            /* Store dead time A B settings and checks range of the value */
        	parameters_RAM.boost_dead_time_A_B = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.boost_dead_time_A_B, parameters_MAX_RAM.boost_dead_time_A_B);
            break;
        case BOOST_UART_DT_C_D:
            /* Store dead time C D settings and checks range of the value */
        	parameters_RAM.boost_dead_time_C_D = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.boost_dead_time_C_D, parameters_MAX_RAM.boost_dead_time_C_D);
            break;
        case UART_SYNC_ON_DLY:
			/* Delay of the rising edge of the synchronous after the rising edge of PWM C or D. */
			parameters_RAM.synch_ON_dly = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_ON_dly, parameters_MAX_RAM.synch_ON_dly);
			break;
        case UART_SYNC_ON_DCM_DLY:
			/* Delay of the rising edge of the synchronous after the rising edge of PWM A or B in DCM. */
			parameters_RAM.synch_ON_DCM_dly = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_ON_DCM_dly, parameters_MAX_RAM.synch_ON_DCM_dly);
			break;			
        case UART_SYNC_OFF_DLY:
			/* Delay of the falling edge of the synchronous after the falling edge of PWM A or B. */
			parameters_RAM.synch_OFF_dly = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_OFF_dly, parameters_MAX_RAM.synch_OFF_dly);
			break;		
        case UART_SYNC_ON_IL_F:
			/* Switch on delay of the synchronous adjustment factor by the current measurement setting. */
			parameters_RAM.synch_ON_il_factor = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_ON_il_factor, parameters_MAX_RAM.synch_ON_il_factor);
			break;
        case UART_SYNC_ON_IL_R:
			/* Switch on delay of the synchronous adjustment ratio by the current measurement setting. */
			parameters_RAM.synch_ON_il_ratio = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_ON_il_ratio, parameters_MAX_RAM.synch_ON_il_ratio);
			break;
        case UART_SYNC_OFF_IL_F:
			/* Store switch off delay of the synchronous adjustment factor by the current measurement */
			parameters_RAM.synch_OFF_il_factor = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_OFF_il_factor, parameters_MAX_RAM.synch_OFF_il_factor);
			break;
        case UART_SYNC_OFF_IL_R:
			/* Store switch off delay of the synchronous adjustment ratio by the current measurement */
			parameters_RAM.synch_OFF_il_ratio = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_OFF_il_ratio, parameters_MAX_RAM.synch_OFF_il_ratio);
			break;
        case UART_SYNC_DCM:
			/* Store DCM mode threshold for the synchronous rectifiers. */
			parameters_RAM.synch_DCM = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_DCM, parameters_MAX_RAM.synch_DCM);
			break;
        case UART_SYNC_ICP:
			/* Store deactivation threshold for the synchronous rectifiers. */
			parameters_RAM.synch_ICP = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.synch_ICP, parameters_MAX_RAM.synch_ICP);
			break;
        case UART_START_EN:
            /* Enables the start or stops the converter. */
            if (UART_rx_buffer.msg.payload.ui16[0] == UART_ON_OFF_START) converter_ctr.status |= START_EN;
            else if (UART_rx_buffer.msg.payload.ui16[0] == UART_ON_OFF_STOP) converter_ctr.status &= ~START_EN;
            break;
        case UART_BRIDGE_AB_IL_F:
			/* Store dead time adjustment factor by current measurement. */
			parameters_RAM.bridge_A_B_il_factor = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.bridge_A_B_il_factor, parameters_MAX_RAM.bridge_A_B_il_factor);
			break;
        case UART_BRIDGE_CD_IL_F:
			/* Store dead time adjustment factor by current measurement. */
			parameters_RAM.bridge_C_D_il_factor = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.bridge_C_D_il_factor, parameters_MAX_RAM.bridge_C_D_il_factor);
			break;
        case UART_BRIDGE_IL_R:
			/* Store dead time adjustment ratio by current measurement. */
			parameters_RAM.bridge_il_ratio = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.bridge_il_ratio, parameters_MAX_RAM.bridge_il_ratio);
			break;
        case UART_DEBUG_FAN:
			/* Store debugging mode for the fan protection. */
			parameters_RAM.debug_fan = UART_rx_buffer.msg.payload.ui16[0];
			break;
        case UART_DEBUG_VIN:
			/* Store debugging mode for the fan protection. */
			parameters_RAM.debug_vin = UART_rx_buffer.msg.payload.ui16[0];
			break;
        case UART_DEBUG_SOFT:
			/* Store debugging mode for the soft start protection. */
			parameters_RAM.debug_soft = UART_rx_buffer.msg.payload.ui16[0];
			break;
        case UART_MIN_PHASE:
			/* Minimum allowed phase output of the compensator. */
			parameters_RAM.min_phase = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.min_phase, parameters_MAX_RAM.min_phase);
			break;
        case UART_BURST_PHASE:
			/* Output of the compensator during burst. */
			parameters_RAM.burst_phase = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.burst_phase, parameters_MAX_RAM.burst_phase);
			break;
        case UART_BURST_STOP_LIMIT:
			/* Limit output of the compensator for stopping the PWM and the bursts. */
			parameters_RAM.burst_stop_limit = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.burst_stop_limit, parameters_MAX_RAM.burst_stop_limit);
			break;
        case UART_BURST_LOW_LIMIT:
			/* Low limit for entering the burst mode. */
			parameters_RAM.burst_low_limit = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.burst_low_limit, parameters_MAX_RAM.burst_low_limit);
			break;
        case UART_BURST_HIGH_LIMIT:
			/* High limit for exiting the burst mode. */
			parameters_RAM.burst_high_limit = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.burst_high_limit, parameters_MAX_RAM.burst_high_limit);
			break;
        case UART_BURST_TRAP_CYC:
			/* Number of skipped cycles during burst. */
			parameters_RAM.burst_trap_cyc = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.burst_trap_cyc, parameters_MAX_RAM.burst_trap_cyc);
			break;
        case UART_BURST_LENGHT:
			/* Number of pulses during burst. */
			parameters_RAM.burst_lenght = limit_range(UART_rx_buffer.msg.payload.ui16[0], parameters_MIN_RAM.burst_lenght, parameters_MAX_RAM.burst_lenght);
			/* Set the compare value of burst counter */
			XMC_CCU4_SLICE_SetTimerCompareMatch(BURST_CNT.ccu4_handle->slice_ptr, parameters_RAM.burst_lenght);
			XMC_CCU4_SLICE_SetTimerPeriodMatch(BURST_CNT.ccu4_handle->slice_ptr, parameters_RAM.burst_lenght + 1);
			BURST_CNT.ccu4_handle->kernel_ptr->GCSS = BURST_CNT.ccu4_handle->shadow_mask;
			break;
        case UART_SAVE:
        	converter_ctr.store_params = true;
            break;
//        case UART_BUCK_BOOST_SLCTN:
//            /* Enables the start or stops the converter. */
//            if (UART_rx_buffer.msg.payload.ui16[0] == UART_BOOST_MODE) 
//            {
//            	boost_mode_init();
//            }
//            else if (UART_rx_buffer.msg.payload.ui16[0] == UART_BUCK_MODE) 
//            {
//            	/* Turns OFF converter during mode exchange. */
//            	converter_set_off();
//            	buck_mode_set = 1;
//            }
//            break;
        case UART_RESTORE:
            /** Overwrites actual parameters with default ROM stored values */
            /** \todo Implement restore functionality. */
            break;
        default:
            break;
    }
}
/*---------------------------------------------------------------------------*/
/**
 * \brief   UART receive data.
 * \return  None
 *
 * Non blocking function. No interrupts involved.
 * Checks available data in the reception FIFO and execute command when a
 * message is received.
 * |-------------|-------------|-------------|-------------|-------------|
 *     0x55				CMD			DATA_0		  DATA_1		 CRC
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
inline void uart_receive()
{
	static uint8_t UART_rx_index = 0xFF; /* UART reception buffer index */
	static uint8_t UART_rx_CRC = 0; /* UART reception CRC */
    uint16_t read_val;

    /* Checks new data in the reception FIFO */
    if(XMC_USIC_CH_RXFIFO_GetLevel(PC_COMM.channel))
    {
    	read_val = (uint16_t) PC_COMM.channel->OUTR;
        /* Heading of a UART message */
        if (UART_rx_index == 0xFF)
        {
            /* Message header */
            if (read_val == 0x55) UART_rx_index = 0;
        }
        /* Body of the message. Each message consist of 4 bytes plus 1 byte header. */
        else if (UART_rx_index < 3)
        {
            UART_rx_buffer.raw.ui8[UART_rx_index] = read_val;
            UART_rx_CRC += read_val;
            UART_rx_index++;
        }
        /* Ending of a 3 byte message */
        else
        {
            /* CRC validation */
            if(UART_rx_CRC == read_val)
            {
                /* Interpret the command */
                uart_execute_cmd();
            }
            UART_rx_index = 0xFF;
            UART_rx_CRC = 0x00;
        }
    }
}
/*---------------------------------------------------------------------------*/
/**
 * \brief   UART transmit data.
 * \return  None
 * \param	command	Protocol command to be transmitted.
 * \param	msg		Two byte payload of the message.
 *
 * Non blocking function. No interrupts involved.
 * |-------------|-------------|-------------|-------------|-------------|
 *     0x55				CMD			DATA_0		  DATA_1		 CRC
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void uart_tx_half_word(uint8_t command, uint16_t msg)
{
	uint8_t UART_tx_CRC; /* UART transmission CRC */

	/* Writes fixed header */
	XMC_UART_CH_Transmit(PC_COMM.channel, 0x55);
	/* Writes command code */
	XMC_UART_CH_Transmit(PC_COMM.channel, command);
	UART_tx_CRC = command;
	/* Writes 2 byte payload */
	XMC_UART_CH_Transmit(PC_COMM.channel, ((uint8_t *)&msg)[0]);
	UART_tx_CRC += ((uint8_t *)&msg)[0];
	XMC_UART_CH_Transmit(PC_COMM.channel, ((uint8_t *)&msg)[1]);
	UART_tx_CRC += ((uint8_t *)&msg)[1];
	/* Writes CRC */
	XMC_UART_CH_Transmit(PC_COMM.channel, UART_tx_CRC);
}
/*---------------------------------------------------------------------------*/
/**
 * \brief   UART transmit data.
 * \return  None
 *
 * Non blocking function. No interrupts involved.
 * Update msg_cnt to 0, function will iterate over all possible output messages.
 */

uint16_t ovp_flag = 0;
uint16_t uvp_flag = 0;
// uint16_t ovp_off_flag = 0;
// uint16_t TRAPPING_flag = 0;
// uint16_t soft_TRAPPING_flag = 0;
uint16_t VIN_FAIL_TRAPPING_flag = 0xFF;
uint16_t set_off_flag = 0;
// uint16_t burst_pulse_cnt_TRAPPING_flag = 0;
// uint16_t burst_in_cnt_TRAPPING_flag = 0;
// uint32_t voltage_error_test = 0;
// uint16_t BOOST_VIN_NOISE_OVERSHOOT_test = 0;
// uint16_t zhengfu_flag = 0x0000;//正
// // uint16_t zhengfu_flag2 = 0xFFFF;//正
// uint16_t duty_out_test = 0;

uint16_t phase_out_test = 0;

uint16_t reference_test = 0;
uint16_t ADC_VIN_RESULT_test = 0;
// uint16_t ADC_VIN_RESULT_STOP_test = 0;
// uint32_t adc_vout_measure_test = 0;
// uint16_t STOP_flag = 0;
uint16_t ADC_VO_RESULT_test = 0;
// uint16_t ADC_VO_RESULT_STOP_test = 0;
// uint16_t on_off_STOP = 0;
// uint16_t on_off_no_START_EN = 0;
// uint32_t duty_test = 0;
// uint16_t duty_flag= 0;
uint16_t cr_value_test = 0;
uint16_t duty_init_test = 0;
uint16_t duty_test = 0;
uint16_t duty_test_max = 0;
uint16_t boost_start_up_init_count = 0;
uint16_t boost_start_up_init_HICCUP_count = 0;

uint16_t ADC_IL_RESULT_max_test = 0;
uint16_t ADC_IO_RESULT_max_test = 0;
uint16_t ADC_IL_RESULT_test = 0;
uint16_t ADC_IO_RESULT_test = 0;
uint8_t  adc_ovp_error_PN_flag = 0;
int32_t adc_ovp_error_test = 0;

uint32_t adc_io_measure_power_test = 0;
uint16_t reference_startup_power_test = 0;

uint32_t time_count_while = 0;
uint32_t time_count_power = 0;

uint8_t  adc_ovp_error_voltage_ctr = 0;
int32_t voltage_error_voltage_ctr = 0;

uint16_t reference_new_test = 0;
uint16_t ADC_VO_RESULT_power_test = 0;
uint16_t reference_power_test = 0;
uint8_t ADC_IO_RESULT_PN_test = 0xA0;
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
inline void uart_transmit()
{
	static uint32_t previous_tick; /* Previous transmission tick. */
	uint16_t vout_meter;
	static uint16_t timecount = 0;
    /*
     * Time division of the controller clock. May limit the speed of
     * message transmission to avoid overflow of the FIFO in the PC side.
     */
    if((converter_ctr.time_tick >> UART_TRANSMIT_CLK_DIV) != previous_tick)
    {
        previous_tick = (converter_ctr.time_tick >> UART_TRANSMIT_CLK_DIV);
#if 1
        timecount++;
        if(timecount>1000)//串口上间隔40ms打印
        {
//			XMC_UART_CH_Transmit(PC_COMM.channel, ovp_flag  & 0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, uvp_flag  & 0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, VIN_FAIL_TRAPPING_flag &0xFF);			
			// // XMC_UART_CH_Transmit(PC_COMM.channel, 0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, cr_value_test >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, cr_value_test &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ADC_IO_RESULT >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ADC_IO_RESULT &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xFF);			
			// XMC_UART_CH_Transmit(PC_COMM.channel, burst_pulse_cnt_TRAPPING_flag &0xFF);		

			// XMC_UART_CH_Transmit(PC_COMM.channel, reference_test >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, reference_test &0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, VIN_FAIL_TRAPPING_flag &0xFF);
			
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VIN_RESULT_test >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VIN_RESULT_test &0xFF);						
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xFF);	



			// XMC_UART_CH_Transmit(PC_COMM.channel, converter_ctr.status >>16);
			// XMC_UART_CH_Transmit(PC_COMM.channel, converter_ctr.status >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, converter_ctr.status &0xFF);



			// XMC_UART_CH_Transmit(PC_COMM.channel, duty_init_test >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, duty_init_test &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, duty_test >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, duty_test &0xFF);	
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, duty_test_max >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, duty_test_max &0xFF);					
			// XMC_UART_CH_Transmit(PC_COMM.channel, boost_start_up_init_count >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, boost_start_up_init_count &0xFF);		
			// XMC_UART_CH_Transmit(PC_COMM.channel, boost_start_up_init_HICCUP_count &0xFF);			
			// XMC_UART_CH_Transmit(PC_COMM.channel, burst_in_cnt_TRAPPING_flag &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, soft_TRAPPING_flag &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ovp_off_flag >>8);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ovp_off_flag &0xFF);	
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xFF);

			// XMC_UART_CH_Transmit(PC_COMM.channel, ovp_off_flag >>8);
//			XMC_UART_CH_Transmit(PC_COMM.channel, TRAPPING_flag &0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, set_off_flag &0xFF);

//			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_VIN_RESULT_test >>8)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VIN_RESULT_test &0xFF);
//
//			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_VIN_RESULT_STOP_test >>8)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VIN_RESULT_STOP_test &0xFF);
// //
// 			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_VO_RESULT_test >>8)&0xFF);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VO_RESULT_test &0xFF);
//
//			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_VO_RESULT_STOP_test >>8)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VO_RESULT_STOP_test &0xFF);

//        	XMC_UART_CH_Transmit(PC_COMM.channel, duty_flag &0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, (duty_test >>24)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, (duty_test >>16)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, (duty_test >>8)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, duty_test &0xFF);
//
//			XMC_UART_CH_Transmit(PC_COMM.channel, STOP_flag &0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, (adc_vout_measure_test >>24)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, (adc_vout_measure_test >>16)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, (adc_vout_measure_test >>8)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, adc_vout_measure_test &0xFF);

			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_zero_test_before >>24)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_zero_test_before >>16)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_zero_test_before >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, adc_io_zero_test_before &0xFF);

			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xAA);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_IO_RESULT_PN_test &0xFF);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_IO_RESULT_max_test >>8)&0xFF);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_IO_RESULT_max_test &0xFF);
// //			XMC_UART_CH_Transmit(PC_COMM.channel, 0xAA);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_IO_RESULT_test >>8)&0xFF);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_IO_RESULT_test &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xCC);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xCC);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xCC);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xCC);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_IL_RESULT_max_test >>8)&0xFF);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_IL_RESULT_max_test &0xFF);
// //			XMC_UART_CH_Transmit(PC_COMM.channel, 0xBB);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_IL_RESULT_test >>8)&0xFF);
// 			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_IL_RESULT_test &0xFF);			
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_zero_test >>24)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_zero_test >>16)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_zero_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, adc_io_zero_test &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (phase_out_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, phase_out_test &0xFF);

			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xDD);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xDD);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xDD);
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xDD);

			if(voltage_error_voltage_ctr < 0)
			{
				adc_ovp_error_voltage_ctr = 1;
				XMC_UART_CH_Transmit(PC_COMM.channel, adc_ovp_error_voltage_ctr &0xFF);
				XMC_UART_CH_Transmit(PC_COMM.channel, ((-voltage_error_voltage_ctr) >>24)&0xFF);
				XMC_UART_CH_Transmit(PC_COMM.channel, ((-voltage_error_voltage_ctr) >>16)&0xFF);			
				XMC_UART_CH_Transmit(PC_COMM.channel, ((-voltage_error_voltage_ctr) >>8)&0xFF);
				XMC_UART_CH_Transmit(PC_COMM.channel, (-voltage_error_voltage_ctr) &0xFF);
			}
			else
			{
				adc_ovp_error_voltage_ctr = 0;		
				XMC_UART_CH_Transmit(PC_COMM.channel, adc_ovp_error_voltage_ctr &0xFF);
				XMC_UART_CH_Transmit(PC_COMM.channel, ((voltage_error_voltage_ctr) >>24)&0xFF);
				XMC_UART_CH_Transmit(PC_COMM.channel, ((voltage_error_voltage_ctr) >>16)&0xFF);			
				XMC_UART_CH_Transmit(PC_COMM.channel, ((voltage_error_voltage_ctr) >>8)&0xFF);
				XMC_UART_CH_Transmit(PC_COMM.channel, (voltage_error_voltage_ctr) &0xFF);
			}	
			// XMC_UART_CH_Transmit(PC_COMM.channel, adc_ovp_error_PN_flag &0xFF);
			// // XMC_UART_CH_Transmit(PC_COMM.channel, ((adc_ovp_error_test) >>24)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ((adc_ovp_error_test) >>16)&0xFF);			
			// XMC_UART_CH_Transmit(PC_COMM.channel, ((adc_ovp_error_test) >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_ovp_error_test) &0xFF);

			XMC_UART_CH_Transmit(PC_COMM.channel, 0xAA);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_measure_power_test >>24)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_measure_power_test >>16)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (adc_io_measure_power_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, adc_io_measure_power_test &0xFF);

			XMC_UART_CH_Transmit(PC_COMM.channel, (reference_new_test >>8)&0xFF);
			XMC_UART_CH_Transmit(PC_COMM.channel, reference_new_test &0xFF);

			XMC_UART_CH_Transmit(PC_COMM.channel, 0xBB);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (reference_startup_power_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, reference_startup_power_test &0xFF);
			XMC_UART_CH_Transmit(PC_COMM.channel, (reference_power_test >>8)&0xFF);
			XMC_UART_CH_Transmit(PC_COMM.channel, reference_power_test &0xFF);
			XMC_UART_CH_Transmit(PC_COMM.channel, 0xCC);
			XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_VO_RESULT_power_test >>8)&0xFF);
			XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VO_RESULT_power_test &0xFF);
			 
			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xAA);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (time_count_while >>24)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (time_count_while >>16)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (time_count_while >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, time_count_while &0xFF);

			// XMC_UART_CH_Transmit(PC_COMM.channel, 0xBB);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (time_count_power >>24)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (time_count_power >>16)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (time_count_power >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, time_count_power &0xFF);			

//			XMC_UART_CH_Transmit(PC_COMM.channel, on_off_STOP &0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, on_off_no_START_EN &0xFF);

			// XMC_UART_CH_Transmit(PC_COMM.channel, (reference_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, reference_test &0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (ADC_VIN_RESULT_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, ADC_VIN_RESULT_test &0xFF);			

			// XMC_UART_CH_Transmit(PC_COMM.channel, zhengfu_flag &0xFF);
			//  XMC_UART_CH_Transmit(PC_COMM.channel, (voltage_error_test >>24)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (voltage_error_test >>16)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, (voltage_error_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, voltage_error_test &0xFF);

			// XMC_UART_CH_Transmit(PC_COMM.channel, (BOOST_VIN_NOISE_OVERSHOOT_test >>8)&0xFF);
			// XMC_UART_CH_Transmit(PC_COMM.channel, BOOST_VIN_NOISE_OVERSHOOT_test &0xFF);

//			// XMC_UART_CH_Transmit(PC_COMM.channel, zhengfu_flag2 &0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, (duty_out_test >>8)&0xFF);
//			XMC_UART_CH_Transmit(PC_COMM.channel, duty_out_test &0xFF);

			timecount = 0;
        }
#endif
		/* If the FIFO is already empty fills it again */
		if(!XMC_USIC_CH_TXFIFO_GetLevel(PC_COMM.channel))
		{
			/* Message to be sent depends on msg_cnt value. */
			switch(msg_cnt)
			{
				case 0:
					/* Voltage reference */
					uart_tx_half_word(UART_OUT_V, parameters_RAM.voltage_reference);
					msg_cnt ++;
					break;
				case 1:
					/* Brown in voltage */
					uart_tx_half_word(UART_VIN_MIN_HIGH, parameters_RAM.vin_min_high);
					msg_cnt ++;
					break;
				case 2:
					/* A_B PWM dead time */
					uart_tx_half_word(UART_DT_A_B, parameters_RAM.dead_time_A_B);
					msg_cnt ++;
					break;
				case 3:
					/* C_D PWM dead time */
					uart_tx_half_word(UART_DT_C_D, parameters_RAM.dead_time_C_D);
					msg_cnt ++;
					break;
				case 4:
					/* Synchronous ON delay */
					uart_tx_half_word(UART_SYNC_ON_DLY, parameters_RAM.synch_ON_dly);
					msg_cnt ++;
					break;
				case 5:
					/* Synchronous OFF delay */
					uart_tx_half_word(UART_SYNC_OFF_DLY, parameters_RAM.synch_OFF_dly);
					msg_cnt ++;
					break;
				case 6:
					/* Synchronous ON current dependency factor */
					uart_tx_half_word(UART_SYNC_ON_IL_F, parameters_RAM.synch_ON_il_factor);
					msg_cnt ++;
					break;
				case 7:
					/* Synchronous ON current dependency ratio */
					uart_tx_half_word(UART_SYNC_ON_IL_R, parameters_RAM.synch_ON_il_ratio);
					msg_cnt ++;
					break;
				case 8:
					/* Synchronous OFF current dependency factor */
					uart_tx_half_word(UART_SYNC_OFF_IL_F, parameters_RAM.synch_OFF_il_factor);
					msg_cnt ++;
					break;
				case 9:
					/* Synchronous OFF current dependency ratio */
					uart_tx_half_word(UART_SYNC_OFF_IL_R, parameters_RAM.synch_OFF_il_ratio);
					msg_cnt ++;
					break;
				case 10:
					/* Synchronous normal mode activation */
					uart_tx_half_word(UART_SYNC_DCM, parameters_RAM.synch_DCM);
					msg_cnt ++;
					break;
				case 11:
					/* Synchronous DCM mode activation */
					uart_tx_half_word(UART_SYNC_ICP, parameters_RAM.synch_ICP);
					msg_cnt ++;
					break;
				case 12:
					/* Bridge current factor */
					uart_tx_half_word(UART_BRIDGE_AB_IL_F, parameters_RAM.bridge_A_B_il_factor);
					msg_cnt ++;
					break;
				case 13:
					/* Bridge current factor */
					uart_tx_half_word(UART_BRIDGE_CD_IL_F, parameters_RAM.bridge_C_D_il_factor);
					msg_cnt ++;
					break;
				case 14:
					/* Bridge current ratio */
					uart_tx_half_word(UART_BRIDGE_IL_R, parameters_RAM.bridge_il_ratio);
					msg_cnt ++;
					break;
				case 15:
					/* Soft start in debug mode */
					uart_tx_half_word(UART_DEBUG_SOFT, parameters_RAM.debug_soft);
					msg_cnt ++;
					break;
				case 16:
					/* Vin UVLO in debug mode */
					uart_tx_half_word(UART_DEBUG_VIN, parameters_RAM.debug_vin);
					msg_cnt ++;
					break;
				case 17:
					/* Fan detection in debug mode */
					uart_tx_half_word(UART_DEBUG_FAN, parameters_RAM.debug_fan);
					msg_cnt ++;
					break;
				case 18:
					/* Maximum output of the compensator. */
					uart_tx_half_word(UART_MAX_PHASE, MAX_PHASE);
					msg_cnt ++;
					break;
				case 19:
					/* Minimum output of the compensator */
					uart_tx_half_word(UART_MIN_PHASE, parameters_RAM.min_phase);
					msg_cnt ++;
					break;
				case 20:
					/* Output of the compensator during burst */
					uart_tx_half_word(UART_BURST_PHASE, parameters_RAM.burst_phase);
					msg_cnt ++;
					break;
				case 21:
					/* Stop limit of the PWM */
					uart_tx_half_word(UART_BURST_STOP_LIMIT, parameters_RAM.burst_stop_limit);
					msg_cnt ++;
					break;
				case 22:
					/* Low limit threshold of the burst mode */
					uart_tx_half_word(UART_BURST_LOW_LIMIT, parameters_RAM.burst_low_limit);
					msg_cnt ++;
					break;
				case 23:
					/* High limit threshold of the burst mode */
					uart_tx_half_word(UART_BURST_HIGH_LIMIT, parameters_RAM.burst_high_limit);
					msg_cnt ++;
					break;
				case 24:
					/* Burst skipping cycles */
					uart_tx_half_word(UART_BURST_TRAP_CYC, parameters_RAM.burst_trap_cyc);
					msg_cnt ++;
					break;
				case 25:
					/* Burst length */
					uart_tx_half_word(UART_BURST_LENGHT, parameters_RAM.burst_lenght);
					msg_cnt ++;
					break;
				case 26:
					/* Synchronous ON delay in DCM */
					uart_tx_half_word(UART_SYNC_ON_DCM_DLY, parameters_RAM.synch_ON_DCM_dly);
					msg_cnt ++;
					break;
				case 27:
					/* Synchronous ON delay in DCM */
					uart_tx_half_word(SOFT_VER, ((VERSION << VERSION_BITS) | SUB_VERSION));
					msg_cnt ++;
					break;
				case 28:
					/* Synchronous ON delay in DCM */
					uart_tx_half_word(CONVERTER_ID, CONVERTER);
					msg_cnt ++;
					break;
				case 29:
					/* BOOST A_B PWM dead time */
					uart_tx_half_word(BOOST_UART_DT_A_B, parameters_RAM.boost_dead_time_A_B);
					msg_cnt ++;
					break;
				case 30:
					/* BOOST C_D PWM dead time */
					uart_tx_half_word(BOOST_UART_DT_C_D, parameters_RAM.boost_dead_time_C_D);
					msg_cnt ++;
					break;	
					
				case 31:
					/* Status word. */
					uart_tx_half_word(UART_STATUS_S, converter_ctr.status);
					msg_cnt ++;
					break;
				case 32:
					/* Fault word. */
					uart_tx_half_word(UART_STATUS_F, ((uint16_t *)&converter_ctr.status)[1]);
					/* Keeps sending the status in a loop. */
					msg_cnt ++;
					break;
				case 33:
					/* Voltage output measurement */
					vout_meter = ADC_VO_RESULT;
					uart_tx_half_word(METER_VO, vout_meter);
					/* Keeps sending the status in a loop. */
					msg_cnt ++;
					break;
				case 34:
					/* Current output measurement */
					uart_tx_half_word(METER_IO, current_ctr.adc_io_measure);
					/* Keeps sending the status in a loop. */
					msg_cnt ++;
					break;
				case 35:
					/* Voltage input measurement */
					uart_tx_half_word(METER_VIN, converter_ctr.adc_vin_measure);
					/* Keeps sending the status in a loop. */
					msg_cnt ++;
					break;
				case 36:
					/* Current output measurement */
					uart_tx_half_word(METER_IIN, current_ctr.adc_il_measure);
					/* Keeps sending the status in a loop. */
					msg_cnt ++;
					break;
				case 37:
					/* Current output measurement */
					uart_tx_half_word(NTC_TMP, converter_ctr.ntc_temperature);
					/* Keeps sending the status in a loop. */
					msg_cnt ++;
					break;
				case 38:
					/* Current output measurement */
					uart_tx_half_word(DIE_TMP, converter_ctr.die_temperature);
					/* Keeps sending the status in a loop. */
					msg_cnt ++;
					break;
				default:
					if(msg_cnt<2500)
						msg_cnt++;
					else
						msg_cnt = 31;
					break;
			}
		}
    }
}
/*---------------------------------------------------------------------------*/
/**
 * \brief   Copy parameters from ROM into an intermediate RAM area.
 * \return  None
 *
 * Due to the way Flash memory works, its required to have the parameters stored
 * in an intermediate area.
 * Writing into a Flash area involves as first step writing all the area with 0xFF.
 * The program will access the data in RAM, what is faster.
 */
void load_ROM_parameters()
{
	/** \todo Remove this deactivating the UART IRQ selection in DAVE App. */
    /* Disables UART interrupts that are activated by DAVE init by default . */
    NVIC_DisableIRQ(91);
    NVIC_DisableIRQ(90);
    
    /* If no parameters have been stored by the user up to now. */
	if(parameters_ROM->master_key != MASTER_KEY)
	{
		/* Loads parameters from ROM into the RAM temporal storage. */
		parameters_RAM.voltage_reference = parameters_DFLT.voltage_reference;
		parameters_RAM.dead_time_A_B = parameters_DFLT.dead_time_A_B;
		parameters_RAM.dead_time_C_D = parameters_DFLT.dead_time_C_D;
		parameters_RAM.synch_OFF_dly = parameters_DFLT.synch_OFF_dly;
		parameters_RAM.synch_OFF_il_factor = parameters_DFLT.synch_OFF_il_factor;
		parameters_RAM.synch_OFF_il_ratio = parameters_DFLT.synch_OFF_il_ratio;
		parameters_RAM.synch_ON_dly = parameters_DFLT.synch_ON_dly;
		parameters_RAM.synch_ON_DCM_dly = parameters_DFLT.synch_ON_DCM_dly;
		parameters_RAM.synch_ON_il_factor = parameters_DFLT.synch_ON_il_factor;
		parameters_RAM.synch_ON_il_ratio = parameters_DFLT.synch_ON_il_ratio;
		parameters_RAM.synch_DCM = parameters_DFLT.synch_DCM;
		parameters_RAM.synch_ICP = parameters_DFLT.synch_ICP;
		parameters_RAM.debug_vin = parameters_DFLT.debug_vin;
		parameters_RAM.debug_fan = parameters_DFLT.debug_fan;
		parameters_RAM.debug_soft = parameters_DFLT.debug_soft;
		parameters_RAM.bridge_A_B_il_factor = parameters_DFLT.bridge_A_B_il_factor;
		parameters_RAM.bridge_C_D_il_factor = parameters_DFLT.bridge_C_D_il_factor;
		parameters_RAM.bridge_il_ratio = parameters_DFLT.bridge_il_ratio;
		parameters_RAM.min_phase = parameters_DFLT.min_phase;
		parameters_RAM.burst_stop_limit = parameters_DFLT.burst_stop_limit;
		parameters_RAM.burst_low_limit = parameters_DFLT.burst_low_limit;
		parameters_RAM.burst_high_limit = parameters_DFLT.burst_high_limit;
		parameters_RAM.burst_phase = parameters_DFLT.burst_phase;
		parameters_RAM.burst_trap_cyc = parameters_DFLT.burst_trap_cyc;
		parameters_RAM.burst_lenght = parameters_DFLT.burst_lenght;
		parameters_RAM.vin_min_high = parameters_DFLT.vin_min_high;
		parameters_RAM.boost_dead_time_A_B = parameters_DFLT.boost_dead_time_A_B;
		parameters_RAM.boost_dead_time_C_D = parameters_DFLT.boost_dead_time_C_D;

		parameters_RAM.debug_vin = parameters_DFLT.debug_vin;
		parameters_RAM.debug_soft = parameters_DFLT.debug_soft;
		parameters_RAM.debug_fan = parameters_DFLT.debug_fan;
	}
	/* Take the stored parameters set by the user GUI from the ROM area. */
	else
	{
		/* Loads parameters from ROM into the RAM temporal storage. */
		parameters_RAM.voltage_reference = parameters_ROM->voltage_reference;
		parameters_RAM.dead_time_A_B = parameters_ROM->dead_time_A_B;
		parameters_RAM.dead_time_C_D = parameters_ROM->dead_time_C_D;
		parameters_RAM.synch_OFF_dly = parameters_ROM->synch_OFF_dly;
		parameters_RAM.synch_OFF_il_factor = parameters_ROM->synch_OFF_il_factor;
		parameters_RAM.synch_OFF_il_ratio = parameters_ROM->synch_OFF_il_ratio;
		parameters_RAM.synch_ON_dly = parameters_ROM->synch_ON_dly;
		parameters_RAM.synch_ON_DCM_dly = parameters_ROM->synch_ON_DCM_dly;
		parameters_RAM.synch_ON_il_factor = parameters_ROM->synch_ON_il_factor;
		parameters_RAM.synch_ON_il_ratio = parameters_ROM->synch_ON_il_ratio;
		parameters_RAM.synch_DCM = parameters_ROM->synch_DCM;
		parameters_RAM.synch_ICP = parameters_ROM->synch_ICP;
		parameters_RAM.bridge_A_B_il_factor = parameters_ROM->bridge_A_B_il_factor;
		parameters_RAM.bridge_C_D_il_factor = parameters_ROM->bridge_C_D_il_factor;
		parameters_RAM.bridge_il_ratio = parameters_ROM->bridge_il_ratio;
		parameters_RAM.min_phase = parameters_ROM->min_phase;
		parameters_RAM.burst_stop_limit = parameters_ROM->burst_stop_limit;
		parameters_RAM.burst_low_limit = parameters_ROM->burst_low_limit;
		parameters_RAM.burst_high_limit = parameters_ROM->burst_high_limit;
		parameters_RAM.burst_phase = parameters_ROM->burst_phase;
		parameters_RAM.burst_trap_cyc = parameters_ROM->burst_trap_cyc;
		parameters_RAM.burst_lenght = parameters_ROM->burst_lenght;
		parameters_RAM.vin_min_high = parameters_ROM->vin_min_high;
		parameters_RAM.boost_dead_time_A_B = parameters_ROM->boost_dead_time_A_B;
		parameters_RAM.boost_dead_time_C_D = parameters_ROM->boost_dead_time_C_D;
		
		parameters_RAM.debug_vin = parameters_ROM->debug_vin;
		parameters_RAM.debug_fan = parameters_ROM->debug_fan;
		parameters_RAM.debug_soft = parameters_ROM->debug_soft;
	}
	/* Loads parameters from ROM into the RAM temporal storage. */
	parameters_MIN_RAM.voltage_reference = parameters_MIN.voltage_reference;
	parameters_MIN_RAM.dead_time_A_B = parameters_MIN.dead_time_A_B;
	parameters_MIN_RAM.dead_time_C_D = parameters_MIN.dead_time_C_D;
	parameters_MIN_RAM.synch_OFF_dly = parameters_MIN.synch_OFF_dly;
	parameters_MIN_RAM.synch_OFF_il_factor = parameters_MIN.synch_OFF_il_factor;
	parameters_MIN_RAM.synch_OFF_il_ratio = parameters_MIN.synch_OFF_il_ratio;
	parameters_MIN_RAM.synch_ON_dly = parameters_MIN.synch_ON_dly;
	parameters_MIN_RAM.synch_ON_DCM_dly = parameters_MIN.synch_ON_DCM_dly;
	parameters_MIN_RAM.synch_ON_il_factor = parameters_MIN.synch_ON_il_factor;
	parameters_MIN_RAM.synch_ON_il_ratio = parameters_MIN.synch_ON_il_ratio;
	parameters_MIN_RAM.synch_DCM = parameters_MIN.synch_DCM;
	parameters_MIN_RAM.synch_ICP = parameters_MIN.synch_ICP;
	parameters_MIN_RAM.bridge_A_B_il_factor = parameters_MIN.bridge_A_B_il_factor;
	parameters_MIN_RAM.bridge_C_D_il_factor = parameters_MIN.bridge_C_D_il_factor;
	parameters_MIN_RAM.bridge_il_ratio = parameters_MIN.bridge_il_ratio;
	parameters_MIN_RAM.min_phase = parameters_MIN.min_phase;
	parameters_MIN_RAM.burst_stop_limit = parameters_MIN.burst_stop_limit;
	parameters_MIN_RAM.burst_low_limit = parameters_MIN.burst_low_limit;
	parameters_MIN_RAM.burst_high_limit = parameters_MIN.burst_high_limit;
	parameters_MIN_RAM.burst_phase = parameters_MIN.burst_phase;
	parameters_MIN_RAM.burst_trap_cyc = parameters_MIN.burst_trap_cyc;
	parameters_MIN_RAM.burst_lenght = parameters_MIN.burst_lenght;
	parameters_MIN_RAM.vin_min_high = parameters_MIN.vin_min_high;
	parameters_MIN_RAM.boost_dead_time_A_B = parameters_MIN.boost_dead_time_A_B;
	parameters_MIN_RAM.boost_dead_time_C_D = parameters_MIN.boost_dead_time_C_D;
	parameters_MIN_RAM.debug_vin = parameters_MIN.debug_vin;
	parameters_MIN_RAM.debug_fan = parameters_MIN.debug_fan;
	parameters_MIN_RAM.debug_soft = parameters_MIN.debug_soft;
	
	/* Loads parameters from ROM into the RAM temporal storage. */
	parameters_MAX_RAM.voltage_reference = parameters_MAX.voltage_reference;
	parameters_MAX_RAM.dead_time_A_B = parameters_MAX.dead_time_A_B;
	parameters_MAX_RAM.dead_time_C_D = parameters_MAX.dead_time_C_D;
	parameters_MAX_RAM.synch_OFF_dly = parameters_MAX.synch_OFF_dly;
	parameters_MAX_RAM.synch_OFF_il_factor = parameters_MAX.synch_OFF_il_factor;
	parameters_MAX_RAM.synch_OFF_il_ratio = parameters_MAX.synch_OFF_il_ratio;
	parameters_MAX_RAM.synch_ON_dly = parameters_MAX.synch_ON_dly;
	parameters_MAX_RAM.synch_ON_DCM_dly = parameters_MAX.synch_ON_DCM_dly;
	parameters_MAX_RAM.synch_ON_il_factor = parameters_MAX.synch_ON_il_factor;
	parameters_MAX_RAM.synch_ON_il_ratio = parameters_MAX.synch_ON_il_ratio;
	parameters_MAX_RAM.synch_DCM = parameters_MAX.synch_DCM;
	parameters_MAX_RAM.synch_ICP = parameters_MAX.synch_ICP;
	parameters_MAX_RAM.bridge_A_B_il_factor = parameters_MAX.bridge_A_B_il_factor;
	parameters_MAX_RAM.bridge_C_D_il_factor = parameters_MAX.bridge_C_D_il_factor;
	parameters_MAX_RAM.bridge_il_ratio = parameters_MAX.bridge_il_ratio;
	parameters_MAX_RAM.min_phase = parameters_MAX.min_phase;
	parameters_MAX_RAM.burst_stop_limit = parameters_MAX.burst_stop_limit;
	parameters_MAX_RAM.burst_low_limit = parameters_MAX.burst_low_limit;
	parameters_MAX_RAM.burst_high_limit = parameters_MAX.burst_high_limit;
	parameters_MAX_RAM.burst_phase = parameters_MAX.burst_phase;
	parameters_MAX_RAM.burst_trap_cyc = parameters_MAX.burst_trap_cyc;
	parameters_MAX_RAM.burst_lenght = parameters_MAX.burst_lenght;
	parameters_MAX_RAM.vin_min_high = parameters_MAX.vin_min_high;
	parameters_MAX_RAM.boost_dead_time_A_B = parameters_MAX.boost_dead_time_A_B;
	parameters_MAX_RAM.boost_dead_time_C_D = parameters_MAX.boost_dead_time_C_D;
	parameters_MAX_RAM.debug_vin = parameters_MAX.debug_vin;
	parameters_MAX_RAM.debug_fan = parameters_MAX.debug_fan;
	parameters_MAX_RAM.debug_soft = parameters_MAX.debug_soft;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief   Check that parameters in RAM are insight of a valid range.
 * \return  None
 *
 * Mostly useful after first run of the software, when all the parameters might
 * be 0 after uploading the firmware. Dangerous situation. The ranges are quite
 * wide and do not guarantee safe operation.
 * Safe operation is up to the user.
 */
void check_RAM_parameters()
{
	/* Checks all parameters are of the range delimited by the constants min and constants max. */
	parameters_RAM.voltage_reference = limit_range(parameters_RAM.voltage_reference, parameters_MIN.voltage_reference, parameters_MAX.voltage_reference);
	parameters_RAM.dead_time_A_B = limit_range(parameters_RAM.dead_time_A_B, parameters_MIN.dead_time_A_B, parameters_MAX.dead_time_A_B);
	parameters_RAM.dead_time_C_D = limit_range(parameters_RAM.dead_time_C_D, parameters_MIN.dead_time_C_D, parameters_MAX.dead_time_C_D);
	parameters_RAM.synch_OFF_dly = limit_range(parameters_RAM.synch_OFF_dly, parameters_MIN.synch_OFF_dly, parameters_MAX.synch_OFF_dly);
	parameters_RAM.synch_OFF_il_factor = limit_range(parameters_RAM.synch_OFF_il_factor, parameters_MIN.synch_OFF_il_factor, parameters_MAX.synch_OFF_il_factor);
	parameters_RAM.synch_OFF_il_ratio = limit_range(parameters_RAM.synch_OFF_il_ratio, parameters_MIN.synch_OFF_il_ratio, parameters_MAX.synch_OFF_il_ratio);
	parameters_RAM.synch_ON_dly = limit_range(parameters_RAM.synch_ON_dly, parameters_MIN.synch_ON_dly, parameters_MAX.synch_ON_dly);
	parameters_RAM.synch_ON_DCM_dly = limit_range(parameters_RAM.synch_ON_DCM_dly, parameters_MIN.synch_ON_DCM_dly, parameters_MAX.synch_ON_DCM_dly);
	parameters_RAM.synch_ON_il_factor = limit_range(parameters_RAM.synch_ON_il_factor, parameters_MIN.synch_ON_il_factor, parameters_MAX.synch_ON_il_factor);
	parameters_RAM.synch_ON_il_ratio = limit_range(parameters_RAM.synch_ON_il_ratio, parameters_MIN.synch_ON_il_ratio, parameters_MAX.synch_ON_il_ratio);
	parameters_RAM.synch_DCM = limit_range(parameters_RAM.synch_DCM, parameters_MIN.synch_DCM, parameters_MAX.synch_DCM);
	parameters_RAM.synch_ICP = limit_range(parameters_RAM.synch_ICP, parameters_MIN.synch_ICP, parameters_MAX.synch_ICP);
	parameters_RAM.bridge_A_B_il_factor = limit_range(parameters_RAM.bridge_A_B_il_factor, parameters_MIN.bridge_A_B_il_factor, parameters_MAX.bridge_A_B_il_factor);
	parameters_RAM.bridge_C_D_il_factor = limit_range(parameters_RAM.bridge_C_D_il_factor, parameters_MIN.bridge_C_D_il_factor, parameters_MAX.bridge_C_D_il_factor);
	parameters_RAM.bridge_il_ratio = limit_range(parameters_RAM.bridge_il_ratio, parameters_MIN.bridge_il_ratio, parameters_MAX.bridge_il_ratio);
	parameters_RAM.min_phase = limit_range(parameters_RAM.min_phase, parameters_MIN.min_phase, parameters_MAX.min_phase);
	parameters_RAM.burst_stop_limit = limit_range(parameters_RAM.burst_stop_limit, parameters_MIN.burst_stop_limit, parameters_MAX.burst_stop_limit);
	parameters_RAM.burst_low_limit = limit_range(parameters_RAM.burst_low_limit, parameters_MIN.burst_low_limit, parameters_MAX.burst_low_limit);
	parameters_RAM.burst_high_limit = limit_range(parameters_RAM.burst_high_limit, parameters_MIN.burst_high_limit, parameters_MAX.burst_high_limit);
	parameters_RAM.burst_phase = limit_range(parameters_RAM.burst_phase, parameters_MIN.burst_phase, parameters_MAX.burst_phase);
	parameters_RAM.burst_trap_cyc = limit_range(parameters_RAM.burst_trap_cyc, parameters_MIN.burst_trap_cyc, parameters_MAX.burst_trap_cyc);
	parameters_RAM.burst_lenght = limit_range(parameters_RAM.burst_lenght, parameters_MIN.burst_lenght, parameters_MAX.burst_lenght);
	parameters_RAM.vin_min_high = limit_range(parameters_RAM.vin_min_high, parameters_MIN.vin_min_high, parameters_MAX.vin_min_high);
	parameters_RAM.boost_dead_time_A_B = limit_range(parameters_RAM.boost_dead_time_A_B, parameters_MIN.boost_dead_time_A_B, parameters_MAX.boost_dead_time_A_B);
	parameters_RAM.boost_dead_time_C_D = limit_range(parameters_RAM.boost_dead_time_C_D, parameters_MIN.boost_dead_time_C_D, parameters_MAX.boost_dead_time_C_D);
}
/**}@*/
